﻿using System;
using System.Collections.Generic;
using Xunit;
using Vulcano.Helpers;

namespace DatetimeTests
{
    public class FuzzyDateTimeTestsptBr
    {
        private readonly int _todayweekday;
        private readonly DateTime _today;
        private FuzzyDateTime _fuzzy;

        public FuzzyDateTimeTestsptBr()
        {
            _today = DateTime.Today;
            _todayweekday = (int)DateTime.Today.DayOfWeek;
            var container = AutofacConfig.Configure("Vulcano.Helpers.ptBRParser");
            _fuzzy = new FuzzyDateTime((IList<IDateTimeParser>) container.Resolve<IEnumerable<IDateTimeParser>>());
            
            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="direction">int 1-> forward (next) , -1-> backwards (last)</param>
        /// <param name="dayOfWeek">int</param>
        /// <returns>Datetime</returns>
        private DateTime WeekDayCalc(int direction, int dayOfWeek)
        {
            var diff = direction * (dayOfWeek - _todayweekday);
            if (diff <= 0)
            {
                diff = 7 + diff;
            }
            return _today.AddDays(direction * diff);
        }


        [Fact]
        public void Yesterday()
        {
            var yesterday = _fuzzy.Parse("ontem");
            Assert.Equal(_today.AddDays(-1), yesterday);
            
        }

        [Fact]
        public void Now()
        {
            var now = _fuzzy.Parse("agora");
            Assert.Equal(DateTime.Now, now);

        }

        [Fact]
        public void Today()
        {
            var today = _fuzzy.Parse("hoje");
            Assert.Equal(_today,today);

        }

        [Fact]
        public void Tomorrow()
        {
            var tomorrow = _fuzzy.Parse("amanhã");
            Assert.Equal(_today.AddDays(1), tomorrow);

            //anarfa mode=on
            var anarfatomorrow = _fuzzy.Parse("amanha");
            Assert.Equal(_today.AddDays(1), anarfatomorrow);
            
        }
        
        #region Next

        [Fact]
        public void NextNDays()
        {
            var nextdays = _fuzzy.Parse("próximos 2 dias");
            Assert.Equal(_today.AddDays(2), nextdays);

            //Analfabeto mode=On
            var anarfanextdays = _fuzzy.Parse("proximos 2 dias");
            Assert.Equal(_today.AddDays(2), anarfanextdays);
        }

        [Fact]
        public void NextWeekDay()
        {
      
            var direction = 1;
            
            //sunday
            var nextsunday = _fuzzy.Parse("próximo domingo");
            Assert.Equal(WeekDayCalc(direction,(int)DayOfWeek.Sunday), nextsunday);
            
            //monday
            var nextmonday = _fuzzy.Parse("próxima segunda-feira");
            Assert.Equal(WeekDayCalc(direction, (int)DayOfWeek.Monday), nextmonday);

            //tuesday
            var nexttuesday = _fuzzy.Parse("próxima terça-feira");
            Assert.Equal(WeekDayCalc(direction, (int)DayOfWeek.Tuesday), nexttuesday);

            //wednesday
            var nextwednesday = _fuzzy.Parse("próxima quarta-feira");
            Assert.Equal(WeekDayCalc(direction, (int)DayOfWeek.Wednesday), nextwednesday);

            //thursday
            var nextthursday = _fuzzy.Parse("próxima quinta-feira");
            Assert.Equal(WeekDayCalc(direction, (int)DayOfWeek.Thursday), nextthursday);

            //friday
            var nextfriday = _fuzzy.Parse("próxima sexta-feira");
            Assert.Equal(WeekDayCalc(direction, (int)DayOfWeek.Friday), nextfriday);

            //saturday
            var nextsaturday = _fuzzy.Parse("próximo sábado");
            Assert.Equal(WeekDayCalc(direction, (int)DayOfWeek.Saturday), nextsaturday);

        }

      
        [Fact]
        public void NextWeek()
        {
            var nextweek = _fuzzy.Parse("próxima semana");
            Assert.Equal(_today.AddDays(7), nextweek);
            
        }

        [Fact]
        public void SemanaQueVem()
        {
            var sem1 = _fuzzy.Parse("semana que vem");
            Assert.Equal(_today.AddDays(7), sem1);
        }

        [Fact]
        public void MesQueVem()
        {
            var fut = _fuzzy.Parse("mês que vem");
            Assert.Equal(_today.AddMonths(1), fut);
        }

        [Fact]
        public void AnoQueVem()
        {
            var fut = _fuzzy.Parse("ano que vem");
            Assert.Equal(_today.AddYears(1), fut);
        }

        [Fact]
        public void SemanaPassada()
        {
            var sem1 = _fuzzy.Parse("semana passada");
            Assert.Equal(_today.AddDays(-7), sem1);
        }

        [Fact]
        public void MesPassado()
        {
            var fut = _fuzzy.Parse("mês passado");
            Assert.Equal(_today.AddMonths(-1), fut);
        }

        [Fact]
        public void AnoPassado()
        {
            var fut = _fuzzy.Parse("ano passado");
            Assert.Equal(_today.AddYears(-1), fut);
        }


        [Fact]
        public void NextNWeeks()
        {
            var nextweek = _fuzzy.Parse("próximas 4 semanas");
            Assert.Equal(_today.AddDays(28), nextweek);

            var nextweek2 = _fuzzy.Parse("proximas 2 semanas");
            Assert.Equal(_today.AddDays(14), nextweek2);
            
        }

        [Fact]
        public void NextMonth()
        {
            var nextmonth = _fuzzy.Parse("próximo mês");
            
            Assert.Equal(_today.AddMonths(1), nextmonth);

        }

        [Fact]
        public void NextNMonths()
        {
            var nextmonth = _fuzzy.Parse("próximos 2 mêses");

            Assert.Equal(_today.AddMonths(2), nextmonth);

        }

        [Fact]
        public void NextYear()
        {
            var nextyear = _fuzzy.Parse("próximo ano");
            Assert.Equal(_today.AddYears(1), nextyear);

        }

        [Fact]
        public void NextNYears()
        {
            var nextyear = _fuzzy.Parse("próximos 3 anos");
            Assert.Equal(_today.AddYears(3), nextyear);

            //ajudar os anarfa
            var nextanarfayear = _fuzzy.Parse("proximos 2 anos");
            Assert.Equal(_today.AddYears(2), nextanarfayear);

        }
        
        #endregion

        #region Ago

        
        [Fact]
        //May fail, not a 100% accurate method
        //Pode falhar, esse metodo não é 100% preciso
        public void NSecondsAgo()
        {
            var secondago = _fuzzy.Parse("1 segundo atrás");
            Assert.Equal(DateTime.Now.AddSeconds(-1), secondago);

            var secondsago = _fuzzy.Parse("2 segundos atrás");
            Assert.Equal(DateTime.Now.AddSeconds(-2), secondsago);
        }

        [Fact]
        //May fail, not a 100% accurate method
        //Pode falhar, esse metodo não é 100% preciso
        public void NMinutesAgo()
        {
            var minuteago = _fuzzy.Parse("1 minuto atrás");
            Assert.Equal(DateTime.Now.AddMinutes(-1), minuteago);

            var minutesago = _fuzzy.Parse("2 minutos atrás");
            Assert.Equal(DateTime.Now.AddMinutes(-2), minutesago);
        }

        [Fact]
        public void NHoursAgo()
        {
            var hourago = _fuzzy.Parse("1 hora atrás");
            Assert.Equal(DateTime.Now.AddHours(-1), hourago);

            var hoursago = _fuzzy.Parse("5 horas atrás");
            Assert.Equal(DateTime.Now.AddHours(-5), hoursago);

        }

        [Fact]
        public void NDaysAgo()
        {
            var dayago = _fuzzy.Parse("1 dia atrás");
            Assert.Equal(_today.AddDays(-1), dayago);

            var daysago = _fuzzy.Parse("2 dias atrás");
            Assert.Equal(_today.AddDays(-2), daysago);

        }

        [Fact]
        public void NWeeksAgo()
        {
            var weeksago = _fuzzy.Parse("2 semanas atrás");
            Assert.Equal(_today.AddDays(-14), weeksago);

        }

        [Fact]
        public void NMonthsAgo()
        {
            var monthsago = _fuzzy.Parse("2 mêses atrás");
            Assert.Equal(_today.AddMonths(-2), monthsago);

        }

        [Fact]
        public void NYearsAgo()
        {
            var yearsago = _fuzzy.Parse("2 anos atrás");
            Assert.Equal(_today.AddYears(-2), yearsago);

        }


        #endregion


        [Fact]
        public void InNSeconds()
        {
            var test = _fuzzy.Parse("em 2 segundos");
            Assert.Equal(DateTime.Now.AddSeconds(2), test);

            var test2 = _fuzzy.Parse("daqui a 2 segundos");
            Assert.Equal(DateTime.Now.AddSeconds(2), test2);
        }

        [Fact]
        public void InNMinutes()
        {
            var test = _fuzzy.Parse("em 2 minutos");
            Assert.Equal(DateTime.Now.AddMinutes(2), test);

            var test2 = _fuzzy.Parse("daqui a 2 minutos");
            Assert.Equal(DateTime.Now.AddMinutes(2), test2);
        }

        [Fact]
        public void InNHours()
        {
            var test = _fuzzy.Parse("em 2 horas");
            Assert.Equal(DateTime.Now.AddHours(2), test);

            var test2 = _fuzzy.Parse("daqui a 2 horas");
            Assert.Equal(DateTime.Now.AddHours(2), test2);
        }

        [Fact]
        public void InNDays()
        {
            var test = _fuzzy.Parse("em 2 dias");
            Assert.Equal(_today.AddDays(2), test);

            var test2 = _fuzzy.Parse("daqui a 2 dias");
            Assert.Equal(_today.AddDays(2), test2);
        }

        [Fact]
        public void InNWeeks()
        {
            var test = _fuzzy.Parse("em 2 semanas");
            Assert.Equal(_today.AddDays(14), test);

            var test2 = _fuzzy.Parse("daqui a 2 semanas");
            Assert.Equal(_today.AddDays(14), test2);
        }

        [Fact]
        public void InNMonths()
        {
            var test = _fuzzy.Parse("em 2 meses");
            Assert.Equal(_today.AddMonths(2), test);

            var test2 = _fuzzy.Parse("daqui a 2 meses");
            Assert.Equal(_today.AddMonths(2), test2);
        }

        [Fact]
        public void InNYears()
        {
            var test = _fuzzy.Parse("em 2 anos");
            Assert.Equal(_today.AddYears(2), test);

            var test2 = _fuzzy.Parse("daqui a 2 anos");
            Assert.Equal(_today.AddYears(2), test2);
        }



    }

    
}
